今天我們來玩玩 hook 的測試吧,今天會用到的API有
直接進入正題,這邊寫了一個簡單的 customer hook 叫做 useCounter
import { useState } from "react";
function useCounter(initialValue: number = 0 ) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(count => count + 1);
const decrement = () => setCount(count => count - 1);
return { count, increment, decrement };
}
export default useCounter;
首先我們來個錯誤示範,我們用一般的方式來使用 useCounter
import useCounter from "./index";
describe("useCounter 測試", () => {
it("測試 useCounter 初始值", () => {
const { count } = useCounter(0)
expect(count).toBe(0);
});
});
看起來好像沒問題,但當你輸入 npm run test
時,你就會發現
Warning: Invalid hook call.
原因是因為 useState 只能在 function Component 內被呼叫,這時候就是 renderHook 大顯神威的時候了,我們將 renderHook import 進來,透過 renderHook return 的 result 來拿到 useCounter 的狀態,非常好用
import useCounter from "./index";
import { renderHook } from "@testing-library/react";
describe("useCounter 測試", () => {
it("測試 useCounter 初始值", () => {
const { result } = renderHook(() => useCounter());
expect(result.current.count).toBe(0);
});
});
那我們重新輸入 npm run test
PASS src/utils/hooks/useCounter/index.test.ts
Test Suites: 2 passed, 2 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 5.12 s
那接下來我們使用 increment() 來操作一下狀態,為了操作 TestComponent 我們將 act 也 import 進來,這邊我們要把更新 state 的操作放在 act 的 callback
底下
import useCounter from "./index";
import { renderHook, act} from "@testing-library/react";
describe("useCounter 測試", () => {
it("測試 useCounter 初始值", () => {
const { result } = renderHook(() => useCounter());
expect(result.current.count).toBe(0);
});
it("測試 useCounter increment", () => {
const { result } = renderHook(() => useCounter());
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
});
npm run test
PASS src/utils/hooks/useCounter/index.test.ts
Test Suites: 2 passed, 2 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: 5.166 s
寫測試時記得要將所有會用到的 case 都加入喔~
import useCounter from "./index";
import { renderHook, act} from "@testing-library/react";
describe("useCounter 測試", () => {
it("測試 useCounter 初始值", () => {
const { result } = renderHook(() => useCounter());
expect(result.current.count).toBe(0);
});
it("測試 useCounter 設置初始值", () => {
const { result } = renderHook(() => useCounter(10));
expect(result.current.count).toBe(10);
});
it("測試 useCounter increment", () => {
const { result } = renderHook(() => useCounter());
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
it("測試 useCounter decrement", () => {
const { result } = renderHook(() => useCounter(10));
act(() => {
result.current.decrement();
});
expect(result.current.count).toBe(9);
});
});
簡單的 hook 測試就先介紹到這邊,明天再繼續寫測試吧!